/*------------------------------------------------------*/
/* Rater Controller  define		                        */
/*                                                      */
/* InfoDataBuffer.h		                               */
/*                                                      */
/* Copyright (C) CyberNaut.com.cn                       */
/* All rights reserved                                  */
/*                                                      */
/* Author                                               */
/*    Quark zhou (quark.zhou@cybernaut.com.cn)          */
/*                                                      */
/* History                                              */
/*    03/23/2006  Create                                */
/*                                                      */
/*------------------------------------------------------*/
#ifndef __INFO_DATA_BUFFER_H__
#define __INFO_DATA_BUFFER_H__

#include "CmDefines.h"
#include "CmMutex.h"


#include <list>
#include <vector>
using namespace std;

#define LI_FRAME_DROP		0x01
#define LP_FRAME_DROP		0x02
#define SI_FRAME_DROP		0x04
#define SP_FRAME_DROP		0x08
 
class CInfoMemPool;
class CInfoDataItem;
class CInfoDataBuffer;
//class ICmTransport;
class IConnection;
class IAVSession;

class CInfoDataItem
{
public:
	CInfoDataItem( ): m_dwLength( 0), m_bFlowType( 0), m_lpData( NULL) { }
	~CInfoDataItem( ) { }
public:
	DWORD				m_dwLength;
	BYTE				m_bFlowType;
	BYTE *				m_lpData;
};

class CInfoMemPool
{
public:
	CInfoMemPool( const DWORD dwMemSize = 0, const DWORD dwMaxBlockSize = 0);
	~CInfoMemPool( );
	
	//if dwSize != m_dwMemSize,an normal new operator will be called	
	void * Alloc( const DWORD dwSize);
	//if dwSize != m_dwMemSize,an normal delete operator will be called	
	void Free( void * pPointer, const DWORD dwSize);
protected:
	// Alloc mem pool
	void AllocMemPool( );
	// Frem mem pool
	void FreeMemPool( );
private:
	vector< void *>		m_MemPool;			// every member in the pool is a pointer
	const DWORD			m_dwMemSize;		// each members' size	
	const DWORD			m_dwMaxBlockSize;	// max members in the pool
};

// we will add and delete the item in the list in one thread,
// so a mutex is not added here.
class CInfoDataBuffer
{
public:
	CInfoDataBuffer( const DWORD dwMemSize, const DWORD dwMaxBlockSize);
	virtual~CInfoDataBuffer( );
	
	// Append an item in the list from the end
	BOOL AppendItem( CInfoDataItem& aDataItem);
	// Pop an item in the list from the begin and the item not be sent,but don't remove it.
	BOOL PopItem( CInfoDataItem& aDataItem);
	// must be called to alloc mem, before AppendItem() called
	void * Alloc( );
	// must be called to free mem, after PopItem() and the buffer is used
	void Free( void * pPointer);
	//
	void Clear( );
	// If have an item to be sent
	BOOL IsEmpty( ) {
		return( m_DataBuffer.empty( ));
	}
	UINT Size( ) {
		return( m_DataBuffer.size( ));
	}
	CmResult DeliveryData( 
		IConnection* pTransport, 
		BOOL bAbortOnSendFail = FALSE);

	BOOL NeedDropPacket( BYTE aType);
	BYTE DropPackets( );
protected:
	BOOL CleanUpBuffer( BYTE aType);
	void SetFlag( BYTE aType, BYTE & aFlag);
private:
	BYTE							m_bDropFlag;
	const DWORD						m_dwMemSize;
	CInfoMemPool					m_MemPool;
	typedef list< CInfoDataItem>	DataBuffer;
	DataBuffer						m_DataBuffer;
#ifdef _INFO_MUTEX_
	CCmMutexThread					m_Mutex;
#endif
};
#endif //__INFO_DATA_BUFFER_H__


